#include <stdio.h>     
#include <unistd.h>    
#include "ohos_init.h" 
#include "cmsis_os2.h" 

#include "sle_client.h"     
#include "wifi_connecter.h" 
#define SSD1306
#ifdef SSD1306
#include "oled_ssd1306.h"        
#endif

#include "lwip/netifapi.h"

#define PARAM_HOTSPOT_SSID "WifiAP"

#define PARAM_HOTSPOT_PSK "Near-link"

#ifndef PARAM_SERVER_ADDR
//#define PARAM_SERVER_ADDR "192.168.1.14" // your PC IP address
#define PARAM_SERVER_ADDR "192.168.1.216" // your PC IP address
#endif

#ifndef PARAM_SERVER_PORT
#define PARAM_SERVER_PORT 9090
#endif

int client_socket;

#ifdef USE_UDP
int SendDataToMinitor(char *sendData, unsigned int dataLength)
{
    struct sockaddr_in sin = {0};
    struct sockaddr_in serverAddr = {0};
    /* create socket */
    int sClient = socket(AF_INET, SOCK_DGRAM, 0);
    if (sClient == -1) {
        printf("create socket Fialed\r\n");
        close(sClient);
        return -1;
    }

    printf("data len = %d\r\n", dataLength);
    // 对方ip和端口号
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(PARAM_SERVER_PORT); 
    serverAddr.sin_addr.s_addr = inet_addr(PARAM_SERVER_ADDR);
    printf("data sent to %s:%d\r\n", PARAM_SERVER_ADDR, PARAM_SERVER_PORT);

    int len = sizeof(sin);
    sendto(sClient, sendData, dataLength, 0, (struct sockaddr*)&serverAddr, len);
    close(sClient);
    return 0;
}
#else
int SendDataToMinitor(char *sendData, unsigned int dataLength)
{
    printf("data len = %d\r\n", dataLength);
    send(client_socket, sendData, dataLength, 0);
    printf("Data sent to client\n");
    return 0;
}
#endif

#define PORT 9090
#define MAX_CONNECTIONS 10

void tcp_server_task(void *arg) 
{
    int server_fd;
    struct sockaddr_in address;
    int addrlen = sizeof(address);

    // 创建socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        return;
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PARAM_SERVER_PORT);

    // 绑定socket到指定地址和端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        return;
    }

    // 监听连接
    if (listen(server_fd, MAX_CONNECTIONS) < 0) {
        perror("listen failed");
        return;
    }

    printf("Server listening on port %d...\n", PORT);

    // 接受新连接
    if ((client_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("accept failed");
        return;
    }

    printf("New connection accepted\n");
    sle_reset_last_address();

    // 保持连接直到客户端断开
    while (1) {
        char buffer[1024] = {0};
        // 检查客户端是否有数据发送，如果没有数据，recv会阻塞，直到有数据或者连接断开
        int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
        if (bytes_received <= 0) {
            // 客户端已经关闭连接，或者发生错误
            if (bytes_received == 0) {
                printf("Client disconnected\n");
            } else {
                perror("recv failed");
            }
            // 关闭连接
            close(client_socket);
            // 重新监听新的连接
            if ((client_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
                perror("accept failed");
                return;
            }
            printf("New connection accepted\n");
            sle_reset_last_address();
        } else {
            // 在这里处理接收到的数据
            printf("Received data: %s\n", buffer);
        }
        // 延时一段时间，避免过于频繁地发送数据
        // sleep(1); // 延时5秒，你可以根据需要调整这个时间
    }

    // 关闭服务器socket
    close(server_fd);
}


static void SleTask(char *arg)
{
    (void)arg;

#ifdef SSD1306
    // 初始化SSD1306
    OledInit();
    // 全屏黑色
    OledFillScreen(0x00);
    // 显示字符串
    OledShowString(20, 0, "SLE-Craft", FONT8x16);   

#endif

    if (ConnectToHotspot(PARAM_HOTSPOT_SSID, PARAM_HOTSPOT_PSK) != 0)
    {
        
        printf("[SleTask] Connect to AP failed\n");                        
#ifdef SSD1306
        OledShowString(2, 2, "AP:Err", FONT8x16);   
#endif
        return;
    }

#ifdef SSD1306
    // OledShowString(2, 2, "AP: Connected", FONT8x16);
    OledShowString(2, 3, "IP:", FONT6x8);
    OledShowString(20, 3, ip_str, FONT6x8);
#endif

    // 创建TCP服务器任务
    osThreadAttr_t attr;
    attr.name = "TcpServerTask";
    attr.stack_size = 1024 * 10;
    attr.priority = osPriorityNormal;

    if (osThreadNew(tcp_server_task, NULL, &attr) == NULL) {
        printf("Failed to create TcpServerTask!\n");
    } else {
        printf("TcpServerTask created successfully!\n");
    }
    
    sle_set_server_name("sle_server");

    sle_client_init();

#ifdef SSD1306
    OledShowString(2, 4, "SLE: Scanning", FONT8x16);
#endif

    sle_wait_service_found();

#ifdef SSD1306
    OledShowString(2, 4, "SLE: OK", FONT8x16);
#endif

    char data[64] = {0};
    int count = 1;
    while (1)
    {
/*        sprintf(data, "%d", count);
        int ret = sle_client_send_data((uint8_t *)data, strlen(data));

#ifdef SSD1306
        char s[20];
        sprintf(s, "SLE Send: %d", count);
        OledShowString(2, 4, s, FONT8x16);
#endif
        count++;
*/        osDelay(100);        
    }

}

static void SleClientDemo(void)
{
    
    osThreadAttr_t attr;
    attr.name = "SleTask";
    attr.stack_size = 1024 * 10; 
    attr.priority = osPriorityNormal;

    if (osThreadNew(SleTask, NULL, &attr) == NULL)
        printf("[SleClientDemo] Falied to create SleTask!\n");
    else
        printf("[SleClientDemo] Create SleTask successfully!\n");
}

APP_FEATURE_INIT(SleClientDemo);
